package org.etlt.check;

import org.etlt.job.JobContext;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class CheckList {
    final private CheckListSetting checkListSetting;

    private Map<String, CheckPoint> checkPoints = new LinkedHashMap<>();

    private List<CheckResult> checkResults = new ArrayList<>();

    private CheckResultReporter checkResultReporter;

    public CheckListSetting getSetting() {
        return checkListSetting;
    }

    public CheckList(CheckListSetting checkListSetting) {
        this.checkListSetting = checkListSetting;
        this.checkListSetting.getCheckPointSettings().forEach((checkPointSetting -> {
            switch (checkPointSetting.getType()) {
                case VALUE_TO_VALUE:
                    CheckPoint checkPoint = new V2VCheckPoint(checkPointSetting, this);
                    checkPoints.put(checkPoint.getName(), checkPoint);
                    break;
                case EXTRACTOR_TO_EXTRACTOR:
                    CheckPoint checkPoint1 = new E2ECheckPoint(checkPointSetting, this);
                    checkPoints.put(checkPoint1.getName(), checkPoint1);
                    break;
                case EXTRACTOR_TO_VALUE:
                    CheckPoint checkPoint2 = new E2VCheckPoint(checkPointSetting, this);
                    checkPoints.put(checkPoint2.getName(), checkPoint2);
                    break;
            }
        }));
        switch (getSetting().getReportType()){
            case CONSOLE:
                checkResultReporter = new CheckResultConsoleReporter();
                break;
            case HTML:
            case PDF:
                checkResultReporter = new CheckResultVelocityReporter();
                break;
        }

    }

    public String getName() {
        return this.checkListSetting.getName();
    }

    public List<CheckResult> getCheckResults() {
        return checkResults;
    }

    public CheckPoint getCheckPoint(String name) {
        return this.checkPoints.get(name);
    }

    public void check(JobContext context) {
        this.checkResults.clear();
        this.checkPoints.values().forEach(checkPoint -> {
            checkResults.add(checkPoint.check(context));
        });
    }

    public void report(JobContext context) {
        if (this.checkResults.isEmpty())
            check(context);
        //-- report result to console
        this.checkResultReporter.report(context, this);
    }
}
